package ca.seia.comp6521.a2.itemsetstorage;

import gnu.trove.list.TIntList;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.javabi.sizeof.MemoryUtil;

/**
 * @author itoe
 *
 */
public class IntItems implements ExternilizableItems, Comparable<IntItems>{

	private int[] items;
	
	public IntItems(int... values) {
		this.items = values;
	}
	
	public int getItem(int index) {
		return this.items[index];
	}
	

	public int getSize() {
		return this.items.length;
	}


	public int[] getItems() {
		return items;
	}

	public void setItems(int[] items) {
		this.items = items;
	}

	@Override
	public String toString() {
		return "IntItems [items=" + Arrays.toString(items) + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Arrays.hashCode(items);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		IntItems other = (IntItems) obj;
		if (!Arrays.equals(items, other.items))
			return false;
		return true;
	}
	
	public boolean containsAtLeastOneItem(TIntList infrequentItems) {
		boolean containsAtLeastOneItem = false;
		for(int item: this.getItems()) {
			if(infrequentItems.contains(item)) {
				containsAtLeastOneItem = true;
				break;
			}
		}
		return containsAtLeastOneItem;
	}
	
	@Override
	public int compareTo(IntItems o) {
		for(int item1Index = 0 ; item1Index < this.getItems().length;item1Index++) {
			if(this.getItem(item1Index) > o.getItem(item1Index) ) {
				return 1;
			} else if(this.getItem(item1Index) < o.getItem(item1Index) ) {
				return -1;
			}
		}
		return 0;
	}
	
	
	public static IntItems generateCandidateTriplet(IntPair pair1, IntPair pair2 ) {
		IntItems triplet = null;
		if( pair1.getValOne() == pair2.getValOne())  {
			if(pair1.getValTwo() <= pair2.getValTwo()) {
				triplet = new IntItems(pair1.getValOne(),pair1.getValTwo(),pair2.getValTwo());
			} else {
				triplet = new IntItems(pair1.getValOne(),pair2.getValTwo(),pair1.getValTwo());
			}
		}
		return triplet;
	}
	
	public static IntItems generateCandidateItems(IntItems items1,IntItems items2, int numberOfItems) {
		int lengthItem1 = items1.getSize() - 1;
		int[] newItems = new int[numberOfItems];
		
		boolean subItemsAllEqual = true;
		for(int item1 = 0 ; item1 < lengthItem1 ; item1++) {
			if(items1.getItem(item1) != items2.getItem(item1)) {
				subItemsAllEqual = false;
				return null;
			}
			newItems[item1] = items1.getItem(item1);
		}
		if (items1.getItem(lengthItem1) <= items2.getItem(lengthItem1)) {
			newItems[lengthItem1] = items1.getItem(lengthItem1);
			newItems[lengthItem1+1] = items2.getItem(lengthItem1);
		}else {
			newItems[lengthItem1] = items2.getItem(lengthItem1);
			newItems[lengthItem1+1] = items1.getItem(lengthItem1);
		}
		return new IntItems(newItems);
	}
	
	//TODO maybe omit using string builder for just simple strings
	@Override
	public String toExternalFormat() {
		StringBuilder builder = new StringBuilder();
		int count = 0;
		int length = this.getItems().length;
		for( int item: this.getItems()) {
			if (count == length - 1) {
				builder.append(item);
			}else {
				builder.append(item + " ");
			}
			count ++;
		}
		return builder.toString();
	}
	
	public static void main(String[] args) throws IllegalAccessException {
		IntItems quaduplet = new IntItems(1,2,3,4,5,6,7,8,9,10);
		IntItems triplet2 = new IntItems(1,2);
		
		Map<IntItems,Integer> map = new HashMap<IntItems,Integer>();
		map.put(quaduplet, 1);
		System.out.println(map.get(new IntItems(1,2,3,4)));
		
		System.out.println("size of quadruplet with array is = " + MemoryUtil.sizeOf(quaduplet));
		System.out.println("size of double with array is = " + MemoryUtil.sizeOf(triplet2));
		System.out.println("size of quadruplet with char is" + MemoryUtil.sizeOf(new CharItems(1,2,3,4,5,6,7,8,9,10)));
		
		IntDecade decade = new IntDecade();
		decade.setVal1(1);
		decade.setVal2(1);
		decade.setVal3(1);
		decade.setVal4(1);
		decade.setVal5(1);
		decade.setVal6(1);
		decade.setVal7(1);
		decade.setVal8(1);
		decade.setVal9(1);
		decade.setVal10(1);
		
		CharDecade charDecade = new CharDecade();
		charDecade.setVal1((char) 1);
		charDecade.setVal2((char) 1);
		charDecade.setVal3((char) 1);
		charDecade.setVal4((char) 1);
		charDecade.setVal5((char) 1);
		charDecade.setVal6((char) 1);
		charDecade.setVal7((char) 1);
		charDecade.setVal8((char) 1);
		charDecade.setVal9((char) 1);
		charDecade.setVal10((char) 1);
		
		System.out.println("size if decade is " + MemoryUtil.sizeOf(decade));
		System.out.println("size if charDecade is " + MemoryUtil.sizeOf(charDecade));
	}


}
